﻿#ifndef _COULD_MSG_H_
#define _COULD_MSG_H_

#define CLOUD_SIGNATURE					'cPxS'
#define CLOUD_VERSION_1_0				0x00010000

#define MAX_PACKET_SIZE					4096		//! 发送的包最大不允许超过这个大小

#ifndef MAX_PATH
#define MAX_PATH						260
#endif

#define UDP_BROADCAST_PORT				3767		//! 广播到此端口
#define UDP_RECV_PORT					3768		//! 通过此端口接受消息
#define TCP_LISTEN_PORT					3769		//! 通过此端口接受消息
#define BROADCAST_ADDRESS				0xE0000101	//! 组播地址 224.0.1.1

#define CLOUD_NAME_LENGTH				128
#define CLOUD_ID_LENGTH					128
#define DEVICE_ID_LENGTH				128
#define DEVICE_NAME_LENGTH				128
#define DEVICE_TYPE_LENGTH				128
#define TOKEN_LENGTH					16
#define TOKEN_MASK_LENGTH				64

#define CloudCmd_AckFlag				0x00010000

#define CloudCmd_SearchAll				0x00000001
#define CloudCmd_SearchAllAck			(CloudCmd_SearchAll | CloudCmd_AckFlag)
#define CloudCmd_Search					0x00000002
#define CloudCmd_SearchAck				(CloudCmd_Search | CloudCmd_AckFlag)

#define CloudCmd_ExchangeTokenMask		0x00000003
#define CloudCmd_ExchangeTokenMaskAck	(CloudCmd_ExchangeTokenMask | CloudCmd_AckFlag)
#define CloudCmd_Login					0x00000004
#define CloudCmd_LoginAck				(CloudCmd_Login | CloudCmd_AckFlag)
#define CloudCmd_ExchangeInformation	0x00000005
#define CloudCmd_ExchangeInformationAck	(CloudCmd_ExchangeInformation | CloudCmd_AckFlag)
#define CloudCmd_SearchOther			0x00000006
#define CloudCmd_SearchOtherAck			(CloudCmd_SearchOther | CloudCmd_AckFlag)

#define CloudCmd_ReportFile				0x00000101
#define CloudCmd_ReportFileAck			(CloudCmd_ReportFile | CloudCmd_AckFlag)
#define CloudCmd_NewFile				0x00000102
#define CloudCmd_NewFileAck				(CloudCmd_NewFile | CloudCmd_AckFlag)
#define CloudCmd_DeleteFile				0x00000103
#define CloudCmd_DeleteFileAck			(CloudCmd_DeleteFile | CloudCmd_AckFlag)
#define CloudCmd_DownloadFile			0x00000104
#define CloudCmd_DownloadFileAck		(CloudCmd_DownloadFile | CloudCmd_AckFlag)
#define CloudCmd_UploadFile				0x00000105
#define CloudCmd_UploadFileAck			(CloudCmd_UploadFile | CloudCmd_AckFlag)
#define CloudCmd_RefreshFile			0x00000106
#define CloudCmd_RefreshFileAck			(CloudCmd_RefreshFile | CloudCmd_AckFlag)

#define CloudCmd_DownloadAddressBook	0x00000201
#define CloudCmd_DownloadAddressBookAck	(CloudCmd_DownloadAddressBook | CloudCmd_AckFlag)
#define CloudCmd_UploadAddressBook		0x00000202
#define CloudCmd_UploadAddressBookAck	(CloudCmd_UploadAddressBook | CloudCmd_AckFlag)

#define CloudCmd_Logout					0x00001000

#define CloudCmd_Heartbeat				0x00002000

#pragma pack(push, 1)

//! 通信消息头。
typedef struct _CLOUDMSG_HDR
{
	DWORD Signature;						/*!< 签名CLOUD_SIGNATURE。 */
	DWORD Version;							/*!< 版本CLOUD_VERSION_1_0。 */
	DWORD CRC;								/*!< CRC校验码。 */
	DWORD Cmd;								/*!< 命令。 */
	DWORD Length;							/*!< 整个消息的长度（以字节为单位）。 */
} CLOUDMSG_HDR, *LPCLOUDMSG_HDR;

//! 通过UDP广播查询网络中存在的云。
typedef struct _CLOUDMSG_SEARCHALL
{
	CLOUDMSG_HDR hdr;						/*!< 消息头，Cmd = CloudCmd_SearchAll。 */
} CLOUDMSG_SEARCHALL, *LPCLOUDMSG_SEARCHALL;

//! 收到UDP广播查询网络中存在的云后，发送给对方的应答消息。
typedef struct _CLOUDMSG_SEARCHALL_ACK
{
	CLOUDMSG_HDR hdr;						/*!< 消息头，Cmd = CloudCmd_SearchAllAck。 */
	WCHAR CloudId[CLOUD_ID_LENGTH];			/*!< 私有云的唯一标识。 */
	WCHAR CloudName[CLOUD_NAME_LENGTH];		/*!< 私有云的名称。 */
} CLOUDMSG_SEARCHALL_ACK, *LPCLOUDMSG_SEARCHALL_ACK;

//! 通过UDP广播查询某个私有云是否存在。
typedef struct _CLOUDMSG_SEARCH
{
	CLOUDMSG_HDR hdr;						/*!< 消息头，Cmd = CloudCmd_Search。 */
	WCHAR CloudId[CLOUD_ID_LENGTH];			/*!< 私有云的唯一标识。 */
} CLOUDMSG_SEARCH, *LPCLOUDMSG_SEARCH;

//! 其它云设备收到新设备的查询消息后，发送给对方的应答消息。
typedef struct _CLOUDMSG_SEARCH_ACK
{
	CLOUDMSG_HDR hdr;						/*!< 消息头，Cmd = CloudCmd_SearchAck。 */
} CLOUDMSG_SEARCH_ACK, *LPCLOUDMSG_SEARCH_ACK;

//! 云设备之间交换TokenMask信息。
typedef struct _CLOUDMSG_EXCHANGE_TOKEN_MASK
{
	CLOUDMSG_HDR hdr;						/*!< 消息头，Cmd = CloudCmd_ExchangeTokenMask。 */
	WCHAR TokenMask[TOKEN_MASK_LENGTH];		/*!< 用来生成验证用的Token。 */
} CLOUDMSG_EXCHANGE_TOKEN_MASK, *LPCLOUDMSG_EXCHANGE_TOKEN_MASK;

//! 云设备之间交换TokenMask信息的应答。
typedef struct _CLOUDMSG_EXCHANGE_TOKEN_MASK_ACK
{
	CLOUDMSG_HDR hdr;						/*!< 消息头，Cmd = CloudCmd_ExchangeTokenMaskAck。 */
	WCHAR TokenMask[TOKEN_MASK_LENGTH];		/*!< 用来生成验证用的Token。 */
} CLOUDMSG_EXCHANGE_TOKEN_MASK_ACK, *LPCLOUDMSG_EXCHANGE_TOKEN_MASK_ACK;

//! 向某个云设备查询与其建立连接的其他云设备。
typedef struct _CLOUDMSG_SEARCH_OTHER
{
	CLOUDMSG_HDR hdr;						/*!< 消息头，Cmd = CloudCmd_SearchOther。 */
} CLOUDMSG_SEARCH_OTHER, *LPCLOUDMSG_SEARCH_OTHER;

//! 对CloudCmd_SearchOther命令的应答。
typedef struct _CLOUDMSG_SEARCH_OTHER_ACK
{
	CLOUDMSG_HDR hdr;						/*!< 消息头，Cmd = CloudCmd_SearchOtherAck。 */
	DWORD Count;							/*! IP地址的个数 */
	DWORD IpList[1];						/*! IP地址列表 */
} CLOUDMSG_SEARCH_OTHER_ACK, *LPCLOUDMSG_SEARCH_OTHER_ACK;

//! 发起认证请求。
typedef struct _CLOUDMSG_LOGIN
{
	CLOUDMSG_HDR hdr;						/*!< 消息头，Cmd = CloudCmd_Login。 */
	BYTE Token[TOKEN_LENGTH];				/*!< 收到CLOUDMSG_SEARCH_ACK包后，用CLOUDMSG_SEARCH_ACK.DeviceTokenMask和云的访问密码生成的Token。 */
} CLOUDMSG_LOGIN, *LPCLOUDMSG_LOGIN;

//! 返回认证结果。
typedef struct _CLOUDMSG_LOGIN_ACK
{
	CLOUDMSG_HDR hdr;						/*!< 消息头，Cmd = CloudCmd_LoginAck。 */
	DWORD Result;							/*!< 认证是否成功，0表示成功，否则为错误码。 */
} CLOUDMSG_LOGIN_ACK, *LPCLOUDMSG_LOGIN_ACK;

//! 云设备之间交换信息。
typedef struct _CLOUDMSG_EXCHANGE_INFORMATION
{
	CLOUDMSG_HDR hdr;						/*!< 消息头，Cmd = CloudCmd_ExchangeInformation。 */
	WCHAR DeviceId[DEVICE_ID_LENGTH];		/*!< 设备的唯一标识，每次重新安装后第一次运行的时候生成，以后不变。 */
	WCHAR DeviceName[DEVICE_NAME_LENGTH];	/*!< 设备的名称。 */
	WCHAR DeviceType[DEVICE_TYPE_LENGTH];	/*!< 设备的类型：手机、平板、电脑等。 */
} CLOUDMSG_EXCHANGE_INFORMATION, *LPCLOUDMSG_EXCHANGE_INFORMATION;

//! 云设备之间交换信息的应答。
typedef struct _CLOUDMSG_EXCHANGE_INFORMATION_ACK
{
	CLOUDMSG_HDR hdr;						/*!< 消息头，Cmd = CloudCmd_ExchangeInformationAck。 */
} CLOUDMSG_EXCHANGE_INFORMATION_ACK, *LPCLOUDMSG_EXCHANGE_INFORMATION_ACK;

//! 文件信息。
typedef struct _CLOUD_FILE_INFORMATION
{
	DWORD UniqueId;							/*!< 该Id对某个设备唯一，不同的设备不唯一，也就是说在不同的设备里，可能存在Id相同的文件。 */
	WCHAR FileName[MAX_PATH];				/*!< 文件名。 */
	LARGE_INTEGER FileSize;					/*!< 文件大小。 */
} CLOUD_FILE_INFORMATION, *LPCLOUD_FILE_INFORMATION;

//! 云设备之间报告文件信息。
typedef struct _CLOUDMSG_REPORT_FILE
{
	CLOUDMSG_HDR hdr;						/*!< 消息头，Cmd = CloudCmd_ReportFile。 */
	DWORD Type;								/*!< 0=清除以前的文件并重新上报，1=增加上报文件，2=结束本次上报。 */
	DWORD FileCount;						/*!< 文件个数。 */
	CLOUD_FILE_INFORMATION FileInfo[1];		/*!< 文件信息。 */
} CLOUDMSG_REPORT_FILE, *LPCLOUDMSG_REPORT_FILE;

//! 云设备之间报告文件信息的应答。
typedef struct _CLOUDMSG_REPORT_FILE_ACK
{
	CLOUDMSG_HDR hdr;						/*!< 消息头，Cmd = CloudCmd_ReportFileAck。 */
} CLOUDMSG_REPORT_FILE_ACK, *LPCLOUDMSG_REPORT_FILE_ACK;

//! 云设备之间新建文件。
typedef struct _CLOUDMSG_NEW_FILE
{
	CLOUDMSG_HDR hdr;						/*!< 消息头，Cmd = CloudCmd_NewFile。 */
	WCHAR FileName[MAX_PATH];				/*!< 新建的文件名。 */
} CLOUDMSG_NEW_FILE, *LPCLOUDMSG_NEW_FILE;

//! 云设备之间新建文件。
typedef struct _CLOUDMSG_NEW_FILE_ACK
{
	CLOUDMSG_HDR hdr;						/*!< 消息头，Cmd = CloudCmd_NewFileAck。 */
	DWORD Result;							/*!< 操作是否成功，0表示成功，否则为错误码。 */
	DWORD UniqueId;							/*!< 新建的文件的Id。 */
} CLOUDMSG_NEW_FILE_ACK, *LPCLOUDMSG_NEW_FILE_ACK;

//! 云设备之间删除文件。
typedef struct _CLOUDMSG_DELETE_FILE
{
	CLOUDMSG_HDR hdr;						/*!< 消息头，Cmd = CloudCmd_DeleteFile。 */
	DWORD FileUniqueId;						/*!< 文件的Id。 */
} CLOUDMSG_DELETE_FILE, *LPCLOUDMSG_DELETE_FILE;

//! 云设备之间删除文件。
typedef struct _CLOUDMSG_DELETE_FILE_ACK
{
	CLOUDMSG_HDR hdr;						/*!< 消息头，Cmd = CloudCmd_DeleteFileAck。 */
	DWORD Result;							/*!< 操作是否成功，0表示成功，否则为错误码。 */
} CLOUDMSG_DELETE_FILE_ACK, *LPCLOUDMSG_DELETE_FILE_ACK;

//! 发起下载文件请求。
typedef struct _CLOUDMSG_DOWNLOAD_FILE
{
	CLOUDMSG_HDR hdr;						/*!< 消息头，Cmd = CloudCmd_DownloadFile。 */
	DWORD FileUniqueId;						/*!< 文件的Id。 */
	LARGE_INTEGER Offset;					/*!< 从文件的哪里开始下载。*/
	LARGE_INTEGER Length;					/*!< 本次下载的长度。 */
} CLOUDMSG_DOWNLOAD_FILE, *LPCLOUDMSG_DOWNLOAD_FILE;

//! 下载文件的应答消息。
typedef struct _CLOUDMSG_DOWNLOAD_FILE_ACK
{
	CLOUDMSG_HDR hdr;						/*!< 消息头，Cmd = CloudCmd_DownloadFileAck。 */
	DWORD FileUniqueId;						/*!< 文件的Id。 */
	DWORD Type;								/*!< 0=传输中，1=传输结束，0xFFFFFFFF=错误Id。 */
	LARGE_INTEGER Offset;					/*!< 本次下载的位置。 */
	ULONG Length;							/*!< 本次下载的长度。 */
	BYTE Buffer[1];							/*!< 本次下载的文件的内容。 */
} CLOUDMSG_DOWNLOAD_FILE_ACK, *LPCLOUDMSG_DOWNLOAD_FILE_ACK;

//! 发起上传文件的请求。
typedef struct _CLOUDMSG_UPLOAD_FILE
{
	CLOUDMSG_HDR hdr;						/*!< 消息头，Cmd = CloudCmd_UploadFile。 */
	CLOUD_FILE_INFORMATION FileInfo;		/*!< 待上传的文件信息。 */
} CLOUDMSG_UPLOAD_FILE, *LPCLOUDMSG_UPLOAD_FILE;

//! 收到上传文件的请求后，发送应答信息，并主动发起一个下载文件的请求。
typedef struct _CLOUDMSG_UPLOAD_FILE_ACK
{
	CLOUDMSG_HDR hdr;						/*!< 消息头，Cmd = CloudCmd_UploadFileAck。 */
} CLOUDMSG_UPLOAD_FILE_ACK, *LPCLOUDMSG_UPLOAD_FILE_ACK;

//! 刷新文件列表。
typedef struct _CLOUDMSG_REFRESH_FILE
{
	CLOUDMSG_HDR hdr;						/*!< 消息头，Cmd = CloudCmd_RefreshFile。 */
} CLOUDMSG_REFRESH_FILE, *LPCLOUDMSG_REFRESH_FILE;

//! 刷新文件列表的应答。
typedef struct _CLOUDMSG_REFRESH_FILE_ACK
{
	CLOUDMSG_HDR hdr;						/*!< 消息头，Cmd = CloudCmd_RefreshFileAck。 */
} CLOUDMSG_REFRESH_FILE_ACK, *LPCLOUDMSG_REFRESH_FILE_ACK;

//! 发起下载地址簿请求。
typedef struct _CLOUDMSG_DOWNLOAD_ADDRESSBOOK
{
	CLOUDMSG_HDR hdr;						/*!< 消息头，Cmd = CloudCmd_DownloadAddressBook。 */
	LARGE_INTEGER Offset;					/*!< 从文件的哪里开始下载。 */
	LARGE_INTEGER Length;					/*!< 下载多少内容。 */
} CLOUDMSG_DOWNLOAD_ADDRESSBOOK, *LPCLOUDMSG_DOWNLOAD_ADDRESSBOOK;

//! 下载文件的应答消息。
typedef struct _CLOUDMSG_DOWNLOAD_ADDRESSBOOK_ACK
{
	CLOUDMSG_HDR hdr;						/*!< 消息头，Cmd = CloudCmd_DownloadAddressBookAck。 */
	DWORD Type;								/*!< 0=传输中，1=传输结束，0xFFFFFFFF=错误。 */
	LARGE_INTEGER Offset;					/*!< 本次下载的位置。 */
	ULONG Length;							/*!< 本次下载的长度。 */
	BYTE Buffer[1];							/*!< 本次下载的文件的内容。 */
} CLOUDMSG_DOWNLOAD_ADDRESSBOOK_ACK, *LPCLOUDMSG_DOWNLOAD_ADDRESSBOOK_ACK;

//! 发起上传地址簿的请求。
typedef struct _CLOUDMSG_UPLOAD_ADDRESSBOOK
{
	CLOUDMSG_HDR hdr;						/*!< 消息头，Cmd = CloudCmd_UploadAddressBook。 */
	LARGE_INTEGER FileSize;					/*!< 待上传的地址簿长度。 */
} CLOUDMSG_UPLOAD_ADDRESSBOOK, *LPCLOUDMSG_UPLOAD_ADDRESSBOOK;

//! 收到上传文件的请求后，发送应答信息，并主动发起一个下载文件的请求。
typedef struct _CLOUDMSG_UPLOAD_ADDRESSBOOK_ACK
{
	CLOUDMSG_HDR hdr;						/*!< 消息头，Cmd = CloudCmd_UploadAddressBookAck。 */
} CLOUDMSG_UPLOAD_ADDRESSBOOK_ACK, *LPCLOUDMSG_UPLOAD_ADDRESSBOOK_ACK;

#pragma pack(pop)

#endif //! _COULD_MSG_H_